package com.lakers.notice.springboot.netty.processor;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.lakers.notice.springboot.model.NoticeFrequentlyKey;
import com.lakers.notice.springboot.model.NoticeRecvInfo;
import com.lakers.notice.springboot.model.NoticeUserInfo;
import com.lakers.notice.springboot.netty.CmdType;
import com.lakers.notice.springboot.netty.SendInfo;
import com.lakers.notice.springboot.netty.UserChannelCtxMap;
import io.netty.channel.ChannelHandlerContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 功能描述: MessageProcessor
 *
 * @author liqin(zxl)
 * @date 2024/5/3
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MessageProcessor extends AbstractMessageProcessor<NoticeRecvInfo>{

    @Override
    public void process(NoticeRecvInfo recvInfo) {
        final NoticeUserInfo sender = recvInfo.getSender();
        log.info("recvInfo is:{}", JSONUtil.toJsonStr(recvInfo));
        final List<NoticeUserInfo> receivers = recvInfo.getReceivers();
        if (CollectionUtil.isEmpty(receivers)){
            return;
        }
        if (isAll(receivers)){
            final List<ChannelHandlerContext> all = UserChannelCtxMap.getAll(sender);
            if (CollectionUtil.isEmpty(all)){
                return;
            }
            for (ChannelHandlerContext ctx : all) {
                final SendInfo<String> message = sendInfo(CmdType.MESSAGE.getCmd(), recvInfo);
                log.info("send message to netty is:{}", JSONUtil.toJsonStr(message));
                ctx.channel().writeAndFlush(message);
            }
            return;
        }
        for (NoticeUserInfo receiver : receivers) {
            ChannelHandlerContext ctx = UserChannelCtxMap.getChannelCtx(receiver.getUserId(), receiver.getTerminal());
            if (Objects.isNull(ctx)) {
                continue;
            }
            final SendInfo<String> message = sendInfo(CmdType.MESSAGE.getCmd(), recvInfo);
            log.info("send message to netty is:{}", JSONUtil.toJsonStr(message));
            ctx.channel().writeAndFlush(message);
        }
    }

    private Boolean isAll(List<NoticeUserInfo> receivers){
        return receivers.stream().map(NoticeUserInfo::getUserId).collect(Collectors.toList())
                .contains(NoticeFrequentlyKey.SYSTEM_PUSH_ALL);
    }

    private SendInfo<String> sendInfo(Integer cmd, NoticeRecvInfo recvInfo){
        SendInfo<String> sendInfo = new SendInfo<>();
        sendInfo.setCmd(cmd);
        sendInfo.setContent(recvInfo.getData());
        sendInfo.setMessageId(recvInfo.getMessageId());
        sendInfo.setTime(DateUtil.now());
        return sendInfo;
    }
}
